package com.zero.guava.samples.Cache;

import com.google.common.base.Ticker;
import com.google.common.cache.*;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * CacheBuilderSpec类以解析代表CacheBuilder配置的字符串的形式来创建CacheBuilder实例,需要说明的是,
 * Guava没有处理编译时异常,这将会导致当传入的字符串无效时,会出现编译时异常.
 */
public class CacheBuilderSpecTest {

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        /**
         *  RemovalNotification表示RemovalLitener对象删除一个条目时接收信号的实例对象,
         *  RemovalNotification类实现了Map.Entry接口,因此,我们可以访问缓存条目中实际的
         *  键和值对象,我们需要注意的是当由于垃圾回收机制条目被移除时,那些value值可能
         *  为null.
         */
        RemovalListener<String, String> listener = new RemovalListener<String, String>() {
            @Override
            public void onRemoval(RemovalNotification<String, String> notification) {
                System.out.println("[" + notification.getKey() + ":" + notification.getValue() + "] is removed!");
            }
        };

        CacheLoader<String, String> loader = new CacheLoader<String, String>() {
            @Override
            public String load(String key) throws Exception {
                Thread.sleep(1000);
                System.out.println(key + " is loaded from a cacheLoader!");
                return key + "'s value";
            }
        };

        //配置CacheBuilder的字符串
        String configString = "concurrencyLevel=10,refreshAfterWrite=5s";

        //解析字符串，创建CacheBuilderSpec实例
        CacheBuilderSpec builderSpec = CacheBuilderSpec.parse(configString);

        //通过CacheBuilderSpec实例构造CacheBuilder实例
        CacheBuilder<Object, Object> cacheBuilder = CacheBuilder.from(builderSpec);

        //ticker:设置缓存条目过期时间
        //removalListener:监听缓存条目的移除
        LoadingCache<String, String> cache = cacheBuilder.ticker(Ticker.systemTicker())
                .expireAfterWrite(1, TimeUnit.SECONDS)
                .removalListener(listener)
                .build(loader);

        cache.put("key1","value1");
        cache.put("key2","value2");
        cache.put("key3","value3");
        cache.put("key4","value4");
        cache.put("key5","value5");
        cache.put("key6","value6");


        Thread.sleep(2000);

        cache.get("key1");
        cache.get("key2");
        cache.get("key3");
    }


}
